package com.googlecode.maratische.google.gui;

import static com.googlecode.maratische.google.MainController.getMainController;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.sql.SQLException;
import java.text.DecimalFormat;
import java.util.List;
import java.util.Locale;

import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableModel;

import com.googlecode.maratische.google.BaseException;
import com.googlecode.maratische.google.DaoAction;
import com.googlecode.maratische.google.MainFrame;
import com.googlecode.maratische.google.dao.PropertyDao;
import com.googlecode.maratische.google.dao.SpamDao;
import com.googlecode.maratische.google.model.Constants;
import com.googlecode.maratische.google.model.Property;
import com.googlecode.maratische.google.model.Spam;

public class SettingsFrame extends JDialog {

	private static final long serialVersionUID = -6315708423962260955L;
	private JComboBox languageSelector = null;
	private JTextField removeItemSettingsField  = null;
	private Locale[] list = getMainController().getSupportedLocales();

	private JCheckBox proxyEnabled = new JCheckBox(getBundleMessage("settingsframe.proxysettings.enable"));
	private JTextField proxyHost = new JTextField(20);
	private JTextField proxyPort = new JTextField(5);
	private JTextField proxyLogin = new JTextField(20);
	private JPasswordField proxyPassword = new JPasswordField(20);
	
	public SettingsFrame(MainFrame mainFrame) throws BaseException {
		this(mainFrame, 0);
	}
	public SettingsFrame(MainFrame mainFrame, int selectedTab) throws BaseException {
		super(mainFrame, true);
		setTitle("Настройки");
		setSize(600, 400);
		ImageIcon icon = new ImageIcon(getClass().getResource("/settings.png"));
		setIconImage(icon.getImage());

		setLayout(new BorderLayout());
		
		JTabbedPane jTabbedPane = new JTabbedPane();
		jTabbedPane.addTab("Настройки", icon, mainSettingsPanel());
		jTabbedPane.addTab("Spam", icon, spamSettingsPanel());

		add(jTabbedPane, BorderLayout.CENTER);
		
		init();
		jTabbedPane.setSelectedIndex(selectedTab);
	}

	private JTable spamTable = null;
	private SpamTableModel spamTableModel = null;
	
	private JPanel spamSettingsPanel() {
		JPanel panel = new JPanel();
		panel.setLayout(new BorderLayout());
		
		spamTableModel = new SpamTableModel();
		spamTable = new JTable(spamTableModel);
		panel.add(new JScrollPane(spamTable), BorderLayout.CENTER);
		
		return panel;
	}
	
	class SpamTableModel extends AbstractTableModel {

		private final String[] columns = new String[] {"id","count","titleType","title","descriptionType","description","date"};
		private SpamDao spamDao = null;
		private List<Spam> list = null;
		
		private static final long serialVersionUID = 2521762700887747364L;
		
		private List<Spam> getList() {
			if (this.list == null) {
				try {
					this.list = getSpamDao().list();
				} catch (SQLException e) {
					getMainController().showError(e);
				} catch (BaseException e) {
					getMainController().showError(e);
				}
			}
			return this.list;
		}
		
		private SpamDao getSpamDao() {
			if (spamDao == null) {
				this.spamDao = DaoAction.getDaoAction().getSpamDao();
			}
			return this.spamDao;
		}
		
		@Override
		public int getColumnCount() {
			return columns.length;
		}
		@Override
		public String getColumnName(int column) {
			return columns[column];
		}
		
		@Override
		public int getRowCount() {
			return getList().size();
		}
		
		@Override
		public Object getValueAt(int row, int column) {
			Spam spam = getList().get(row);
			switch (column) {
			case 0:return spam.getId();
			case 1:return spam.getCount();
			case 2:return spam.getTitleType();
			case 3:return spam.getTitle();
			//TODO остальные пол
			}
			return "";
		}
		
		@Override
		public Class<?> getColumnClass(int columnIndex) {
			switch (columnIndex) {
			case 0:return Integer.class;
			case 1:return Integer.class;
			case 2:return Integer.class;
			case 3:return String.class;
			}
			return String.class;
		}
	}
	
	private JPanel mainSettingsPanel() {
		JPanel panel = new JPanel();
		panel.setLayout(new GridLayout(4, 1));
		JPanel panelLanguage = new JPanel();
		panelLanguage.setBorder(BorderFactory.createEtchedBorder());
		JLabel languageLabel = new JLabel(getBundleMessage("settingsframe.language.selector"));
		panelLanguage.add(languageLabel);
		languageSelector = new JComboBox(new LanguageModel());
		panelLanguage.add(languageSelector);
		languageSelector.setSelectedItem(getMainController().getCurrentLocale().getDisplayName());
		JButton addLocale = new JButton(new ImageIcon(getClass().getResource("/help.png")));
		addLocale.setToolTipText("Add new Locale?");
		addLocale.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				JOptionPane
						.showMessageDialog(
								SettingsFrame.this,
								"<html><body>If you want to add new Locale. Please send me the offer to create new Locale with your language<br/> by email to maratische@gmail.com.</body></html>");
			}
		});
		panelLanguage.add(addLocale);
		panel.add(panelLanguage);
		
		JPanel panelStatistic = new JPanel();
		panelStatistic.setLayout(new GridLayout(3, 1));
		
		JPanel panelRemoveItemSettings = new JPanel();
		panelRemoveItemSettings.setBorder(BorderFactory.createEtchedBorder());
		panelRemoveItemSettings.add(new JLabel(getBundleMessage("settingsframe.removeItemSettings.start")));
		removeItemSettingsField = new JTextField(5);
		removeItemSettingsField.setText("5");
		removeItemSettingsField.setEditable(false);
		panelRemoveItemSettings.add(removeItemSettingsField);
		panelRemoveItemSettings.add(new JLabel(getBundleMessage("settingsframe.removeItemSettings.end")));
		panelStatistic.add(panelRemoveItemSettings);

		File imageDirectory = new File(DaoAction.getDaoAction().getItemDao().getRootMediaFolder());
		File databaseDirectory = new File(System.getProperty("user.home")+File.separator+Constants.RSS_READER_FOLDER_NAME+File.separator+"rssreader");
		double imageFolderSize = 0;
		if (imageDirectory.exists()) {
			imageFolderSize = getFolderSize(imageDirectory)/1024/1024;
		}
		double databaseFolderSize = 0;
		if (databaseDirectory.exists()) {
			databaseFolderSize = getFolderSize(databaseDirectory)/1024/1024;
		}
		
		DecimalFormat formatter = new DecimalFormat("0.#");
		JPanel panelStatisticDatabase = new JPanel();
		StringBuilder labelDatabase = new StringBuilder(getBundleMessage("settingsframe.size.database")).append(" ");
		labelDatabase.append(formatter.format(databaseFolderSize)).append(" ");;
		labelDatabase.append(getBundleMessage("Mb"));
		panelStatisticDatabase.add(new JLabel(labelDatabase.toString()));
		panelStatistic.add(panelStatisticDatabase);
		
		JPanel panelStatisticImages= new JPanel();
		StringBuilder labelImages = new StringBuilder(getBundleMessage("settingsframe.size.images")).append(" ");
		labelImages.append(formatter.format(imageFolderSize)).append(" ");
		labelImages.append(getBundleMessage("Mb"));
		panelStatisticImages.add(new JLabel(labelImages.toString()));
		panelStatistic.add(panelStatisticImages);
		
		panel.add(panelStatistic);

		JPanel panelProxy = new JPanel();
		panelProxy.setBorder(BorderFactory.createEtchedBorder());
		panelProxy.setLayout(new GridLayout(3, 1));
		JPanel panelProxy1 = new JPanel();
		panelProxy1.add(proxyEnabled);
		panelProxy.add(panelProxy1);
		JPanel panelProxy2 = new JPanel();
		panelProxy2.add(new JLabel(getBundleMessage("settingsframe.proxysettings.host")));
		panelProxy2.add(proxyHost);
		panelProxy2.add(new JLabel(getBundleMessage("settingsframe.proxysettings.port")));
		panelProxy2.add(proxyPort);
		panelProxy.add(panelProxy2);
		JPanel panelProxy3 = new JPanel();
		panelProxy3.add(new JLabel(getBundleMessage("settingsframe.proxysettings.login")));
		panelProxy3.add(proxyLogin);
		panelProxy3.add(new JLabel(getBundleMessage("settingsframe.proxysettings.password")));
		panelProxy3.add(proxyPassword);
		panelProxy.add(panelProxy3);
		panel.add(panelProxy);
		
		proxyEnabled.setEnabled(false);
		proxyHost.setEnabled(false);
		proxyPort.setEnabled(false);
		proxyLogin.setEnabled(false);
		proxyPassword.setEnabled(false);
		
		JPanel panelButton = new JPanel();
		panelButton.setBorder(BorderFactory.createEtchedBorder());
		JButton buttonOk = new JButton(getBundleMessage("settingsframe.button.enter"));
		buttonOk.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				save();
			}
		});
		panelButton.add(buttonOk);
		JButton buttonCancel = new JButton(getBundleMessage("settingsframe.button.cancel"));
		buttonCancel.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				close();
			}
		});
		panelButton.add(buttonCancel);
		panel.add(panelButton);
		return panel;
	}
	
	private void init() throws BaseException {
		PropertyDao propertyDao = DaoAction.getDaoAction().getPropertyDao();
		proxyEnabled.setSelected(propertyDao.getPropertyByType(Property.PROPERTY_PROXY_ENABLED).getInteger1().equals(1));
		proxyHost.setText(propertyDao.getPropertyByType(Property.PROPERTY_PROXY_HOST).getString1());
		proxyPort.setText(propertyDao.getPropertyByType(Property.PROPERTY_PROXY_PORT).getInteger1().toString());
		proxyLogin.setText(propertyDao.getPropertyByType(Property.PROPERTY_PROXY_LOGIN).getString1());
		proxyPassword.setText(propertyDao.getPropertyByType(Property.PROPERTY_PROXY_PASSWORD).getString1());
	}

	private final double getFolderSize(File dir) {
		double size = 0;
		for (File file : dir.listFiles()) {
			if (file.isFile())
				size += file.length();
			else
				size += getFolderSize(file);
		}
		return size;
	}

	private void close() {
		this.dispose();
	}

	private void save() {
		Locale selectedLocale = list[languageSelector.getSelectedIndex()];
		if (!getMainController().getCurrentLocale().equals(selectedLocale)) {
			// пользователь изменил локаль
			getMainController().setCurrentLocale(selectedLocale);
			PropertyDao propertyDao = DaoAction.getDaoAction().getPropertyDao();
			Property propertyLocaleLanguage;
			Property propertyLocaleCountry;
			try {
				propertyLocaleLanguage = propertyDao.getPropertyByType(Property.PROPERTY_LOCALE_LANGUAGE);
				propertyLocaleLanguage.setString1(selectedLocale.getLanguage());
				propertyLocaleLanguage = propertyDao.save(propertyLocaleLanguage);

				propertyLocaleCountry = propertyDao.getPropertyByType(Property.PROPERTY_LOCALE_COUNTRY);
				propertyLocaleCountry.setString1(selectedLocale.getCountry());
				propertyLocaleCountry = propertyDao.save(propertyLocaleCountry);

				System.out.println(propertyLocaleLanguage.getString1());
				System.out.println(propertyLocaleCountry.getString1());
			} catch (BaseException e) {
				getMainController().showError(getBundleMessage("settingsframe.save.error"), e);
			} catch (SQLException e) {
				getMainController().showError(getBundleMessage("settingsframe.save.error"), e);
			}
			JOptionPane.showMessageDialog(this, getBundleMessage("settingsframe.have.restart"));
		}
		
		//Property changed
		try {
			PropertyDao propertyDao = DaoAction.getDaoAction().getPropertyDao();
			Property propertyPropxyEnabled = propertyDao.getPropertyByType(Property.PROPERTY_PROXY_ENABLED); 
			if (propertyPropxyEnabled.getInteger1().equals(1) != proxyEnabled.isSelected()) {
				propertyPropxyEnabled.setInteger1(proxyEnabled.isSelected() ? 1 : 0);
				propertyDao.save(propertyPropxyEnabled);
			}
			Property propertyProxyPassword = propertyDao.getPropertyByType(Property.PROPERTY_PROXY_PASSWORD);
			String password = new String(proxyPassword.getPassword());
			if (!propertyProxyPassword.getString1().equals(password)) {
				propertyProxyPassword.setString1(password);
				propertyProxyPassword = propertyDao.save(propertyProxyPassword);
			}
			Property propertyProxyLogin = propertyDao.getPropertyByType(Property.PROPERTY_PROXY_LOGIN);
			if (!propertyProxyLogin.getString1().equals(proxyLogin.getText())) {
				propertyProxyLogin.setString1(proxyLogin.getText());
				propertyDao.save(propertyProxyLogin);
			}
			Property propertyProxyPort = propertyDao.getPropertyByType(Property.PROPERTY_PROXY_PORT);
			if (!propertyProxyPort.getInteger1().toString().equals(proxyPort.getText())) {
				propertyProxyPort.setInteger1(new Integer(proxyPort.getText()));
				propertyProxyPort = propertyDao.save(propertyProxyPort);
			}
			Property propertyProxyHost = propertyDao.getPropertyByType(Property.PROPERTY_PROXY_HOST);
			if (!propertyProxyHost.getString1().equals(proxyHost.getText())) {
				propertyProxyHost.setString1(proxyHost.getText());
				propertyDao.save(propertyProxyHost);
			}
		} catch (NumberFormatException e) {
			JOptionPane.showMessageDialog(this, getBundleMessage("settingsframe.proxysettings.port.error"));
			return;
		} catch (BaseException e) {
			getMainController().showError(e);
		} catch (SQLException e) {
			getMainController().showError(e);
		}
		close();
	}

	public String getBundleMessage(String message) {
		return getMainController().getBundleMessage(message);
	}

	class LanguageModel extends DefaultComboBoxModel {

		@Override
		public int getSize() {
			return list.length;
		}

		@Override
		public Object getElementAt(int index) {
			// TODO Auto-generated method stub
			return list[index].getDisplayName();
		}

		@Override
		public void setSelectedItem(Object anObject) {
			// TODO Auto-generated method stub
			super.setSelectedItem(anObject);
		}

		private static final long serialVersionUID = -8102194007637388564L;

	}
}
